package com.example.myapplication.function.keyboard

import android.util.Log

class PianoSoundGenerator {
    
    companion object {
        private const val SAMPLE_RATE = 44100
        private const val DURATION = 2.0 // 音符持续时间（秒）
        private const val ATTACK_TIME = 0.01
        private const val DECAY_TIME = 0.1
        private const val RELEASE_TIME = 0.5
        private const val SUSTAIN_LEVEL = 0.7
        
        // 钢琴88键频率表 (A0 = 27.5Hz 到 C8 = 4186.0Hz)
        private val NOTE_FREQUENCIES = generatePianoFrequencies()

        // 音色参数
        private const val HARMONICS_COUNT = 8
        private val HARMONICS_AMPLITUDES = floatArrayOf(
            1.0f, 0.5f, 0.3f, 0.2f, 0.15f, 0.1f, 0.05f, 0.02f
        )

        /**
         * 生成钢琴88键频率表
         */
        private fun generatePianoFrequencies(): Map<String, Double> {
            val frequencies = mutableMapOf<String, Double>()
            val noteNames = arrayOf("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")

            // 钢琴键盘从A0 (27.5Hz) 到 C8 (4186.0Hz)
            for (octave in 0..8) {
                for ((noteIndex, noteName) in noteNames.withIndex()) {
                    val midiNumber = 21 + octave * 12 + noteIndex // A0 = 21
                    if (midiNumber in 21..108) { // 88键范围
                        val frequency = 27.5 * Math.pow(2.0, (midiNumber - 21) / 12.0)
                        val fullNoteName = "$noteName$octave"
                        frequencies[fullNoteName] = frequency
                    }
                }
            }
            return frequencies
        }
    }
    
    data class PianoNote(
        val noteName: String,
        val frequency: Double,
        val sampleData: FloatArray,
        val duration: Double = DURATION
    )
    


    /**
     * 使用预计算的钢琴频率表（更准确）
     */
    private fun generatePianoFrequencies2(): Map<String, Double> {
        // 钢琴88键标准频率表 (A0 - C8)
        val standardFrequencies = mapOf(
            // 第0八度
            "A0" to 27.5000, "A#0" to 29.1352, "B0" to 30.8677,

            // 第1八度
            "C1" to 32.7032, "C#1" to 34.6478, "D1" to 36.7081, "D#1" to 38.8909,
            "E1" to 41.2034, "F1" to 43.6535, "F#1" to 46.2493, "G1" to 48.9994,
            "G#1" to 51.9131, "A1" to 55.0000, "A#1" to 58.2705, "B1" to 61.7354,

            // 第2八度
            "C2" to 65.4064, "C#2" to 69.2957, "D2" to 73.4162, "D#2" to 77.7817,
            "E2" to 82.4069, "F2" to 87.3071, "F#2" to 92.4986, "G2" to 97.9989,
            "G#2" to 103.826, "A2" to 110.000, "A#2" to 116.541, "B2" to 123.471,

            // 第3八度
            "C3" to 130.813, "C#3" to 138.591, "D3" to 146.832, "D#3" to 155.563,
            "E3" to 164.814, "F3" to 174.614, "F#3" to 184.997, "G3" to 195.998,
            "G#3" to 207.652, "A3" to 220.000, "A#3" to 233.082, "B3" to 246.942,

            // 第4八度 (中央C所在八度)
            "C4" to 261.626, "C#4" to 277.183, "D4" to 293.665, "D#4" to 311.127,
            "E4" to 329.628, "F4" to 349.228, "F#4" to 369.994, "G4" to 391.995,
            "G#4" to 415.305, "A4" to 440.000, "A#4" to 466.164, "B4" to 493.883,

            // 第5八度
            "C5" to 523.251, "C#5" to 554.365, "D5" to 587.330, "D#5" to 622.254,
            "E5" to 659.255, "F5" to 698.456, "F#5" to 739.989, "G5" to 783.991,
            "G#5" to 830.609, "A5" to 880.000, "A#5" to 932.328, "B5" to 987.767,

            // 第6八度
            "C6" to 1046.50, "C#6" to 1108.73, "D6" to 1174.66, "D#6" to 1244.51,
            "E6" to 1318.51, "F6" to 1396.91, "F#6" to 1479.98, "G6" to 1567.98,
            "G#6" to 1661.22, "A6" to 1760.00, "A#6" to 1864.66, "B6" to 1975.53,

            // 第7八度
            "C7" to 2093.00, "C#7" to 2217.46, "D7" to 2349.32, "D#7" to 2489.02,
            "E7" to 2637.02, "F7" to 2793.83, "F#7" to 2959.96, "G7" to 3135.96,
            "G#7" to 3322.44, "A7" to 3520.00, "A#7" to 3729.31, "B7" to 3951.07,

            // 第8八度
            "C8" to 4186.01
        )

        Log.d("PianoFrequencies", "加载标准频率表，共 ${standardFrequencies.size} 个音符")
        return standardFrequencies
    }
    
    /**
     * 生成钢琴音色样本
     */
    fun generatePianoNote(noteName: String): PianoNote {
        val frequency = NOTE_FREQUENCIES[noteName] ?: throw IllegalArgumentException("Invalid note name: $noteName")
        
        val sampleCount = (SAMPLE_RATE * DURATION).toInt()
        val samples = FloatArray(sampleCount)
        
        // 生成包含谐波的钢琴音色
        for (harmonic in 0 until HARMONICS_COUNT) {
            val harmonicFreq = frequency * (harmonic + 1)
            val harmonicAmp = HARMONICS_AMPLITUDES[harmonic]
            
            for (i in samples.indices) {
                val time = i.toDouble() / SAMPLE_RATE
                val envelope = calculateEnvelope(time)
                
                // 基础正弦波 + 轻微失谐模拟真实钢琴
                val detune = 1.0 + (harmonic * 0.001) // 轻微失谐
                val sample = Math.sin(2.0 * Math.PI * harmonicFreq * detune * time).toFloat()
                
                samples[i] += sample * harmonicAmp * envelope
            }
        }
        
        // 应用总体包络和归一化
        applyMasterEnvelope(samples)
        normalizeSamples(samples)
        
        return PianoNote(noteName, frequency, samples, DURATION)
    }
    
    /**
     * 计算ADSR包络
     */
    private fun calculateEnvelope(time: Double): Float {
        return when {
            time < ATTACK_TIME -> (time / ATTACK_TIME).toFloat() // Attack
            time < ATTACK_TIME + DECAY_TIME -> {
                // Decay to sustain level
                val decayProgress = (time - ATTACK_TIME) / DECAY_TIME
                1.0f - (1.0f - SUSTAIN_LEVEL).toFloat() * decayProgress.toFloat()
            }
            time < DURATION - RELEASE_TIME -> SUSTAIN_LEVEL.toFloat() // Sustain
            else -> {
                // Release
                val releaseProgress = (time - (DURATION - RELEASE_TIME)) / RELEASE_TIME
                SUSTAIN_LEVEL.toFloat() * (1.0f - releaseProgress.toFloat())
            }
        }
    }
    
    /**
     * 应用主包络（模拟钢琴音色特性）
     */
    private fun applyMasterEnvelope(samples: FloatArray) {
        for (i in samples.indices) {
            val time = i.toDouble() / SAMPLE_RATE
            
            // 钢琴特有的包络：快速起音，较慢的衰减
            val pianoEnvelope = when {
                time < 0.02 -> time / 0.02 // 非常快的起音
                time < 0.5 -> Math.exp(-time * 3.0) // 指数衰减
                else -> Math.exp(-time * 6.0) // 更快的后期衰减
            }
            
            samples[i] *= pianoEnvelope.toFloat()
        }
    }
    
    /**
     * 归一化样本数据
     */
    private fun normalizeSamples(samples: FloatArray) {
        var maxAmplitude = 0f
        for (sample in samples) {
            maxAmplitude = maxOf(maxAmplitude, Math.abs(sample))
        }
        
        if (maxAmplitude > 0) {
            val normalizationFactor = 0.8f / maxAmplitude // 留一些headroom
            for (i in samples.indices) {
                samples[i] *= normalizationFactor
            }
        }
    }
    
    /**
     * 生成完整的钢琴音源库
     */
    fun generatePianoSoundLibrary(): Map<String, PianoNote> {
        val soundLibrary = mutableMapOf<String, PianoNote>()
        
        NOTE_FREQUENCIES.keys.forEach { noteName ->
            try {
                val note = generatePianoNote(noteName)
                soundLibrary[noteName] = note
                Log.d("PianoSoundGen", "Generated sound for: $noteName (${note.frequency}Hz)")
            } catch (e: Exception) {
                Log.e("PianoSoundGen", "Failed to generate sound for: $noteName", e)
            }
        }
        
        return soundLibrary
    }
    
    /**
     * 获取所有可用的音符名称
     */
    fun getAvailableNoteNames(): List<String> {
        return NOTE_FREQUENCIES.keys.sortedBy { noteName ->
            NOTE_FREQUENCIES[noteName] ?: 0.0
        }
    }
}